﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using CREAPA.Dominio;
using CREAPA.RepositorioADO;
using System.Web.UI;
using System.Web.UI.WebControls;
using CREAPA.UL.Web.Models;
using CREAPA.UL.Web.HtmlHelpers;
using System.Collections.ObjectModel;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;
using System.Net.Mail;

namespace CREAPA.UL.Web.Controllers
{
    public class FuncionarioController : Controller
    {
        FuncionarioRepositorioADO funcADO = new FuncionarioRepositorioADO();
        CREAPA.Dominio.Funcionario funcionario = new CREAPA.Dominio.Funcionario();
        private siscreaEntitiesBD db = new siscreaEntitiesBD();

        [Authorize]
        public ActionResult Index()
        {
            string usu = User.Identity.Name;
            var permissao = new SelectList(db.FuncionarioPermissoes.Where(p => p.Login == usu && (p.Permissao == 3 || p.Permissao == 11)));

            if (permissao.Count() > 0)
            {
                var listaFunc = funcADO.ListarTodos();
                return View(listaFunc);
            }
            else
            {
                TempData["notice"] = "Você não tem permissão para acessar essa página. É necessária a permissão: 0003";
                return RedirectToAction("../Os/Erro");
            }
        }

        [Authorize]
        public ActionResult ListaFuncionarios()
        {
            var listaFunc = funcADO.ListarTodosAtivos();
            return View(listaFunc);
        }

        public ActionResult ImportaSITAC(string cpf)
        {
            if (cpf != null)
            {
                cpf = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(cpf);
                if (!CREAPA.UL.Web.HtmlHelpers.Validacoes.ValidaCpf(cpf))
                {
                    return new JsonResult()
                    {
                        Data = "CPF Inválido"
                    };
                }
            }
            var funcSITAC = funcADO.ListarPorLoginSITAC(cpf);
            if (funcSITAC != null)
            {
                return new JsonResult()
               {
                   Data = funcSITAC
               };
            }
            else
            {
                return new JsonResult()
                {
                    Data = "CPF não Cadastrado"
                };
            }
        }


        [Authorize]
        public ActionResult Cadastrar()
        {
            ViewBag.IdInsp = new SelectList(db.Inspetorias.OrderBy(p => p.Nome), "Id", "Nome");
            ViewBag.IdCargo = new SelectList(db.Cargoes.OrderBy(p => p.Nome), "Id", "Nome");
            ViewBag.Setor = new SelectList(db.Setors.OrderBy(p => p.Nome), "Id", "Nome");
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Cadastrar(CREAPA.Dominio.Funcionario func)
        {
            ViewBag.IdInsp = new SelectList(db.Inspetorias.OrderBy(p => p.Nome), "Id", "Nome");
            ViewBag.IdCargo = new SelectList(db.Cargoes.OrderBy(p => p.Nome), "Id", "Nome");
            ViewBag.Setor = new SelectList(db.Setors.OrderBy(p => p.Nome), "Id", "Nome");
            var login = new SelectList(db.Funcionarios.Where(p => p.Login == func.Login), "Login", "Login");

            if (func.Pessoa.Fone != null)
                func.Pessoa.Fone = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(func.Pessoa.Fone);

            if (func.Pessoa.CPF != null)
            {
                func.Pessoa.CPF = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(func.Pessoa.CPF);
                if (!CREAPA.UL.Web.HtmlHelpers.Validacoes.ValidaCpf(func.Pessoa.CPF))
                    ModelState.AddModelError("Pessoa.CPF", "CPF inválido.");
            }
            if (login.Count() != 0)
                ModelState.AddModelError("Login", "O Nome de Usuario Já Existe.");

            if (Request.Files.Count != 0)//Algum arquivo foi anexado
            {
                if (Request.Files["FileUpload1"].ContentLength != 0)//Algum arquivo foi anexado
                {
                    string extensao = Path.GetExtension(Request.Files["FileUpload1"].FileName).ToLower();
                    if (!((extensao == ".jpeg") || (extensao == ".png") || (extensao == ".jpg")))
                        ModelState.AddModelError("Assinatura", "Somente são aceitos arquivos JPEG e PNG.");
                    else
                    {
                        byte[] imageBytes = new byte[Request.Files["FileUpload1"].InputStream.Length + 1];
                        Request.Files["FileUpload1"].InputStream.Read(imageBytes, 0, imageBytes.Length);

                        func.Assinatura = imageBytes;
                    }
                }
            }

            if (ModelState.IsValid)
            {
                funcADO.Inserir(func);
                return RedirectToAction("Index");
            }
            else
            {
                return View(func);
            }
        }

        [Authorize]
        public ActionResult Alterar(string login)
        {
            var func = funcADO.ListarPorLogin(login);

            ViewBag.IdInsp = new SelectList(db.Inspetorias.OrderBy(p => p.Nome), "Id", "Nome", func.IdInsp);
            ViewBag.IdCargo = new SelectList(db.Cargoes.OrderBy(p => p.Nome), "Id", "Nome", func.IdCargo);
            ViewBag.Setor = new SelectList(db.Setors.OrderBy(p => p.Nome), "Id", "Nome", func.Setor);

            if (func == null)
            {
                return HttpNotFound();
            }
            return View(func);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Alterar(CREAPA.Dominio.Funcionario func)
        {
            ViewBag.IdInsp = new SelectList(db.Inspetorias.OrderBy(p => p.Nome), "Id", "Nome", func.IdInsp);
            ViewBag.IdCargo = new SelectList(db.Cargoes.OrderBy(p => p.Nome), "Id", "Nome", func.IdCargo);
            ViewBag.Setor = new SelectList(db.Setors.OrderBy(p => p.Nome), "Id", "Nome", func.Setor);

            if (func.Pessoa.Fone != null)
                func.Pessoa.Fone = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(func.Pessoa.Fone);

            if (func.Pessoa.CPF != null)
            {
                func.Pessoa.CPF = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(func.Pessoa.CPF);
                if (!CREAPA.UL.Web.HtmlHelpers.Validacoes.ValidaCpf(func.Pessoa.CPF))
                    ModelState.AddModelError("Pessoa.CPF", "CPF inválido.");
            }

            if (Request.Files["FileUpload1"].ContentLength != 0)//Algum arquivo foi anexado
            {
                string extensao = Path.GetExtension(Request.Files["FileUpload1"].FileName).ToLower();
                if (!((extensao == ".jpeg") || (extensao == ".png") || (extensao == ".jpg")))
                    ModelState.AddModelError("Assinatura", "Somente são aceitos arquivos JPEG e PNG.");
                else
                {
                    byte[] imageBytes = new byte[Request.Files["FileUpload1"].InputStream.Length + 1];
                    Request.Files["FileUpload1"].InputStream.Read(imageBytes, 0, imageBytes.Length);

                    func.Assinatura = imageBytes;
                }
            }

            if (ModelState.IsValid)
            {
                funcADO.Alterar(func);
                return RedirectToAction("Index");
            }
            return View(func);
        }

        public ActionResult GetImage(string login)
        {
            var firstOrDefault = db.Funcionarios.Where(c => c.Login == login).FirstOrDefault();
            if (firstOrDefault != null)
            {
                byte[] image = firstOrDefault.Assinatura;
                if (image != null)
                    return File(image, "image/jpg");
                else return null;

            }
            else
            {
                return null;
            }
        }

        public ActionResult ResetarSenha()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ResetarSenha(CREAPA.Dominio.Funcionario func)
        {
            if (func.Pessoa.CPF != null)
            {
                func.Pessoa.CPF = CREAPA.UL.Web.HtmlHelpers.Validacoes.retornaSoNumero(func.Pessoa.CPF);
                if (!CREAPA.UL.Web.HtmlHelpers.Validacoes.ValidaCpf(func.Pessoa.CPF))
                    ModelState.AddModelError("Pessoa.CPF", "CPF inválido.");
            }
            var funcBD = funcADO.ListarPorLogin(func.Login);
            if (func.Login == funcBD.Login && func.Pessoa.CPF == funcBD.Pessoa.CPF && func.Pessoa.Email == funcBD.Pessoa.Email)
            {
                Random numero = new Random();
                funcBD.NovaSenha = "crea"+numero.Next(100,999).ToString();
                EnviarEmailResetSenha(funcBD);
                funcADO.AlterarSenha(funcBD);
                TempData["NovaSenha"] = "Email De Redefinição de Senha Enviado";
                return RedirectToAction("Login", "Funcionario");
            }
            else
            {
                ModelState.AddModelError("","Dados não cadastrados ou as informações não conferem.");
                return View();
            }
        }
        public ActionResult RedefinirSenha(string login)
        {
            var func = funcADO.ListarPorLogin(login);
                Random numero = new Random();
                func.NovaSenha = "crea"+numero.Next(100,999).ToString();
                EnviarEmailResetSenha(func);
                funcADO.AlterarSenha(func);
                TempData["RedefinirSenha"] = "Email De Redefinição de Senha Enviado";
                return RedirectToAction("Alterar", new { Login=func.Login});
        }

        [HttpGet]
        public ActionResult Login()
        {
            return View();
        }

        [Authorize]
        public ActionResult AlterarSenha()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult AlterarSenha(CREAPA.Dominio.Funcionario func)
        {
            func.Login = User.Identity.Name;
            if (func.Senha != null)
            {
                if (funcADO.IsValid(func.Login, func.Senha))
                {
                    if (func.NovaSenha != null)
                    {

                        if (func.ConfirmarSenha == func.NovaSenha)
                        {
                            funcADO.AlterarSenha(func);
                            TempData["Senha"] = "Senha Alterada com Sucesso";
                            return RedirectToAction("Login", "Funcionario");
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("NovaSenha", "Informe a Nova Senha");
                    }
                    return View();
                }
                else
                {
                    ModelState.AddModelError("Senha", "Senha incorreta!");
                }
                return View(func);
            }
            else
            {
                ModelState.AddModelError("Senha", "Informe a Senha Atual");
            }
            return View(func);
        }

        [HttpPost]
        public ActionResult Login(CREAPA.Dominio.Funcionario func)
        {
            if (string.IsNullOrEmpty(func.Senha))
            {
                ModelState.AddModelError("Senha", "O campo senha deve ser preenchido.");
            }
            else
            {
                if (funcADO.IsValid(func.Login, func.Senha))
                {
                    //if ((DateTime.Now.Hour > 7) && (DateTime.Now.Hour < 17))//Bloqueia fazer OS fora do horário do expediente
                    //{
                        var ativo = new SelectList(db.Funcionarios.Join(db.Pessoas,
                                     p => p.Pessoa.Id, c => c.Id,
                                     (p, c) => new { p.Login, c.Ativo }).Where(m => m.Ativo == true && m.Login == func.Login));
                        if (ativo.Count() > 0)
                        {
                            FormsAuthentication.SetAuthCookie(func.Login, func.RememberMe);
                            Session["usuario"] = func.Login;
                            if (func.Senha == "crea")//No cadastro a senha inicial é crea. Este comando é para forçar a alteração da senha pelo funcionário
                                return RedirectToAction("AlterarSenha", "Funcionario");
                            else
                                return RedirectToAction("Index", "Home");
                        }
                        else
                        {
                            ModelState.AddModelError("", "Usuário Desativado!\nContate o Setor de Recursos Humanos.");
                        }
                    //}
                    //else
                    //{
                    //    ModelState.AddModelError("", "Não é possível acessar o SISCREA fora do horário de expediente");
                    //}
                }
                else
                {
                    ModelState.AddModelError("", "Login incorreto!");
                }
            }
            return View(func);
        }

        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Login", "Funcionario");
        }

        private void EnviarEmailResetSenha(CREAPA.Dominio.Funcionario func)
        {
            //Instancia o objeto
            MailMessage Email = new MailMessage();

            //Atribui ao método From o valor do Remetente 
            Email.From = new MailAddress("<creapainformatica@gmail.com>", "CREA-PA");
            //Email.From = new MailAddress("<nti@creapa.com.br>", "NTI CREA-PA");

            //Define o formato da mensagem (pode ser texto)
            Email.IsBodyHtml = true;

            Email.BodyEncoding = System.Text.Encoding.GetEncoding("iso-8859-1");
                       
            //Envia email com a nova senha

                //Atribui ao método To o valor do Destinatário
                Email.To.Add(func.Pessoa.Email);

                //Subject ou assunto da mensagem
                Email.Subject = "Nova Senha do SiSCREA, Redefinida em " + DateTime.Now.ToString();

                //Atribui ao método corpo o texto da mensagem

                Email.Body = "<html><body><font style='font-family: Verdana; font-size: small'>Prezado(a) " + func.Pessoa.Nome + "," +
           " <br /><br /> Informamos que sua Senha do SiSCREA foi redefinida referente ao usuario \"" + func.Login +"\"." +
           " <br />Sua Nova Senha é:" + func.NovaSenha +
           "<br /><br />Por favor, Recomendamos mudar esta senha para uma de fácil memorização, isso pode ser feito acessando o menu Alterar Senha no SiSCREA." +
           "<br /><br />Esta é uma mensagem enviada automaticamente pelo SiSCREA." +
           "<br /><br />Atenciosamente,<br /><br /><br />Núcleo de Tecnologia da Informação do CREA-PA.<br/><br/> " +
           "Telefone: (91)3219-1155/1156 </body></html>";
            

            //Define a prioridade do Email como Alta
            Email.Priority = MailPriority.High;

            //cria objeto com os dados do SMTP 
            SmtpClient smtp = new SmtpClient();

            //Define o host do SMTP 
            smtp.Host = "smtp.gmail.com";
            //smtp.Host = "192.168.0.3";
            smtp.Port = 587;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new System.Net.NetworkCredential
            ("creapainformatica@gmail.com", "ReS@3)41934");// Enter seders User name and password
            smtp.EnableSsl = true;

            try
            {
                //envia o e-mail através do método .send() 
                smtp.Send(Email);
            }
            catch (Exception erro)
            {
                //Envia a mensagem de erro

            }
            //Exclui o objeto de e-mail da memória 
            Email.Dispose();

        }
    
        //public ActionResult ExportReport()
        //{
        //    List<CREAPA.UL.Web.Models.Cargo> allEverest = new List<CREAPA.UL.Web.Models.Cargo>();
        //    using (siscreaEntitiesBD db = new siscreaEntitiesBD())
        //    {
        //        allEverest = db.Cargoes.ToList();
        //    }

        //    ReportDocument rd = new ReportDocument();
        //    rd.Load(Path.Combine(Server.MapPath("~/Reports"), "CrystalReport1.rpt"));
        //    rd.SetDataSource(allEverest);

        //    Response.Buffer = false;
        //    Response.ClearContent();
        //    Response.ClearHeaders();


        //    try
        //    {
        //        Stream stream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
        //        stream.Seek(0, SeekOrigin.Begin);
        //        return File(stream, "application/pdf", "EverestList.pdf");
        //    }
        //    catch (Exception ex)
        //    {
        //        throw;
        //    }
        //}

    }
}
